#include "bbInput.h"

bbInpt::bbInpt(HWND target /* = NULL */, int width /* = 100 */, int heigth /* = 100 */)
{
	hinstance		= GetModuleHandle(NULL);
	m_screenWidth	= width;
	m_screenHeight	= heigth;
	hwnd			= target;
	m_mouseX		= 0;
	m_mouseY		= 0;
}
bbInpt::~bbInpt()
{
	if(m_mouse)
	{
		m_mouse->Unacquire();
		m_mouse->Release();
		m_mouse = 0;
	}
	if(m_keyboard)
	{
		m_keyboard->Unacquire();
		m_keyboard->Release();
		m_keyboard = 0;
	}
	if(m_directInput)
	{
		m_directInput->Release();
		m_directInput = 0;
	}
}
bool bbInpt::bb_InitInput()
{
	HRESULT result;

	result = DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_directInput, NULL);
	if(FAILED(result))
	{
		MessageBox(hwnd, "DirectInput8Create failed", "DirectInput", MB_ICONERROR | MB_OK);
		return false;
	}
	result = m_directInput->CreateDevice(GUID_SysKeyboard, &m_keyboard, NULL);
	if(FAILED(result))
	{
		MessageBox(hwnd, "CreateDevice failed", "DirectInput", MB_ICONERROR | MB_OK);
		return false;
	}
	result = m_keyboard->SetDataFormat(&c_dfDIKeyboard);
	if(FAILED(result))
	{
		MessageBox(hwnd, "SetDataFormat failed", "DirectInput", MB_ICONERROR | MB_OK);
		return false;
	}
	result = m_keyboard->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
	if(FAILED(result))
	{
		MessageBox(hwnd, "SetCooperativeLevel failed", "DirectInput keyboard", MB_ICONERROR | MB_OK);
		return false;
	}
	result = m_keyboard->Acquire();
	if(FAILED(result))
	{
		MessageBox(hwnd, "Acquire failed", "DirectInput keyboard", MB_ICONERROR | MB_OK);
		return false;
	}
	result = m_directInput->CreateDevice(GUID_SysMouse, &m_mouse, NULL);
	if(FAILED(result))
	{
		MessageBox(hwnd, "CreateDevice failed", "DirectInput mouse", MB_ICONERROR | MB_OK);
		return false;
	}
	result = m_mouse->SetDataFormat(&c_dfDIMouse);
	if(FAILED(result))
	{
		MessageBox(hwnd, "SetDataFormat failed", "DirectInput mouse", MB_ICONERROR | MB_OK);
		return false;
	}
	result = m_mouse->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
	if(FAILED(result))
	{
		MessageBox(hwnd, "SetCooperativeLevel failed", "DirectInput mouse", MB_ICONERROR | MB_OK);
		return false;
	}

	result = m_mouse->Acquire();
	if(FAILED(result))
	{
		MessageBox(hwnd, "Acquire failed", "DirectInput mouse", MB_ICONERROR | MB_OK);
		return false;
	}

	return true;
}
bool bbInpt::bb_UpdateInput()
{
	bool result;

	result = bb_ReadKeyboard();
	if(!result)
	{
		return false;
	}

	result = bb_ReadMouse();
	if(!result)
	{
		return false;
	}

	bb_ProcessInput();

	return true;
}
bool bbInpt::bb_IsKeyPressed(DWORD keyConst)
{
	if(m_keyboardState[keyConst] & 0x80)
	{
		return true;
	}
	return false;
}
void bbInpt::bb_GetMousePos(int &x, int &y)
{
	x = m_mouseX;
	y = m_mouseY;
	return;
}
/*
 *	Private
 */
bool bbInpt::bb_ReadKeyboard(){
	HRESULT result;

	result = m_keyboard->GetDeviceState(sizeof(m_keyboardState), (LPVOID)&m_keyboardState);
	if(FAILED(result))
	{
		if((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED))
		{
			m_keyboard->Acquire();
		}
		else
		{
			return false;
		}
	}

	return true;
}
bool bbInpt::bb_ReadMouse(){
	HRESULT result;

	result = m_mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&m_mouseState);
	if(FAILED(result))
	{
		if((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED))
		{
			m_mouse->Acquire();
		}
		else
		{
			return false;
		}
	}

	return true;
}
void bbInpt::bb_ProcessInput(){
	m_mouseX += m_mouseState.lX;
	m_mouseY += m_mouseState.lY;

	if(m_mouseX < 0)  { m_mouseX = 0; }
	if(m_mouseY < 0)  { m_mouseY = 0; }

	if(m_mouseX > m_screenWidth)  { m_mouseX = m_screenWidth; }
	if(m_mouseY > m_screenHeight) { m_mouseY = m_screenHeight; }

	return;
}